import requests
import logging
from typing import Dict, List, Optional, Any
from ..models.movie import Movie
from ..config.settings import settings

logger = logging.getLogger(__name__)

class TMDBApiService:
    """TMDB API服务类"""
    
    def __init__(self):
        self.api_key = settings.tmdb_api_key
        self.access_token = settings.tmdb_access_token
        self.base_url = settings.tmdb_base_url
        self.image_base_url = settings.tmdb_image_base_url
        self.language = settings.tmdb_language
        self.timeout = 10
        
        self.headers = {
            "accept": "application/json",
            "Authorization": f"Bearer {self.access_token}"
        }
        
        logger.info("TMDBApiService initialized successfully")
    
    def search_person(self, name: str, language: str = None) -> Dict:
        """搜索人员（演员/导演等）"""
        if language is None:
            language = self.language
            
        url = f"{self.base_url}/search/person"
        params = {
            "query": name,
            "language": language,
            "page": 1
        }
        
        try:
            response = requests.get(url, headers=self.headers, params=params, timeout=self.timeout)
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            logger.error(f"Error searching person {name}: {e}")
            return {"results": []}
    
    def get_person_details(self, person_id: int, language: str = None) -> Dict:
        """获取人员详细信息"""
        if language is None:
            language = self.language
            
        url = f"{self.base_url}/person/{person_id}"
        params = {
            "language": language,
            "append_to_response": "movie_credits,tv_credits"
        }
        
        try:
            response = requests.get(url, headers=self.headers, params=params, timeout=self.timeout)
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            logger.error(f"Error getting person details for ID {person_id}: {e}")
            return {}
    
    def get_movies_by_person(self, person_name: str, limit: int = 3, role: str = "all", language: str = None) -> List[Dict]:
        """根据人员姓名获取相关电影
        
        Args:
            person_name: 人员姓名
            limit: 返回电影数量限制
            role: 角色类型 ('actor', 'director', 'all')
            language: 语言设置
        """
        if language is None:
            language = self.language
            
        # 1. 搜索人员
        search_results = self.search_person(person_name, language)
        if not search_results.get('results'):
            logger.warning(f"No person found for name: {person_name}")
            return []
        
        # 取第一个搜索结果
        person = search_results['results'][0]
        person_id = person['id']
        
        # 2. 获取人员详细信息和电影作品
        person_details = self.get_person_details(person_id, language)
        movie_credits = person_details.get('movie_credits', {})
        
        # 3. 根据角色类型筛选电影
        movies = []
        if role in ['actor', 'all']:
            # 演员作品
            cast_movies = movie_credits.get('cast', [])
            movies.extend(cast_movies)
        
        if role in ['director', 'all']:
            # 导演作品
            crew_movies = movie_credits.get('crew', [])
            director_movies = [movie for movie in crew_movies if movie.get('job') == 'Director']
            movies.extend(director_movies)
        
        # 4. 按流行度排序并去重
        unique_movies = {}
        for movie in movies:
            movie_id = movie['id']
            if movie_id not in unique_movies:
                unique_movies[movie_id] = movie
        
        sorted_movies = sorted(unique_movies.values(), 
                             key=lambda x: x.get('popularity', 0), 
                             reverse=True)
        
        # 5. 获取指定数量电影的详细信息
        detailed_movies = []
        for movie in sorted_movies[:limit]:
            movie_details = self.get_movie_details(movie['id'], language)
            if movie_details:
                detailed_movies.append(movie_details)
        
        return detailed_movies
    
    def get_movie_genres(self, language: str = None) -> Dict:
        """获取电影分类列表"""
        if language is None:
            language = self.language
            
        url = f"{self.base_url}/genre/movie/list"
        params = {"language": language}
        
        try:
            response = requests.get(url, headers=self.headers, params=params, timeout=self.timeout)
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            logger.error(f"Error getting movie genres: {e}")
            return {"genres": []}
    
    def get_movies_by_genre(self, genre_id: int, limit: int = 3, language: str = None) -> List[Dict]:
        """根据电影类型ID获取指定数量的电影"""
        if language is None:
            language = self.language
            
        url = f"{self.base_url}/discover/movie"
        params = {
            "with_genres": genre_id,
            "language": language,
            "sort_by": "popularity.desc",  # 按流行度排序
            "page": 1
        }
        
        try:
            response = requests.get(url, headers=self.headers, params=params, timeout=self.timeout)
            response.raise_for_status()
            data = response.json()
            
            # 只返回指定数量的电影
            movies = data.get('results', [])[:limit]
            
            # 获取每部电影的详细信息
            detailed_movies = []
            for movie in movies:
                movie_details = self.get_movie_details(movie['id'], language)
                if movie_details:
                    detailed_movies.append(movie_details)
                    
            return detailed_movies
        except requests.RequestException as e:
            logger.error(f"Error getting movies by genre {genre_id}: {e}")
            return []
    
    def get_movie_details(self, movie_id: int, language: str = None) -> Optional[Dict]:
        """获取电影详细信息"""
        if language is None:
            language = self.language
            
        url = f"{self.base_url}/movie/{movie_id}"
        params = {
            "language": language,
            "append_to_response": "credits,images,videos"
        }
        
        try:
            response = requests.get(url, headers=self.headers, params=params, timeout=self.timeout)
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            logger.error(f"Error getting movie details for ID {movie_id}: {e}")
            return None
    
    def get_image_url(self, path: str, size: str = "w500") -> str:
        """构建图片URL"""
        if not path:
            return ""
        return f"{self.image_base_url}/{size}{path}"
    
    def convert_to_movie(self, tmdb_data: Dict) -> Movie:
        """将TMDB数据转换为Movie模型"""
        try:
            # 提取基本信息
            movie_id = str(tmdb_data.get('id', ''))
            title = tmdb_data.get('title', '') or tmdb_data.get('original_title', '')
            year = self._extract_year(tmdb_data.get('release_date', ''))
            rating = tmdb_data.get('vote_average', 0.0)
            description = tmdb_data.get('overview', '')
            
            # 提取海报URL
            poster_path = tmdb_data.get('poster_path')
            poster_url = self.get_image_url(poster_path) if poster_path else ''
            
            # 提取类型
            genres = tmdb_data.get('genres', [])
            genre_names = [genre.get('name', '') for genre in genres if genre.get('name')]
            genre = genre_names if genre_names else []
            
            # 提取导演信息
            credits = tmdb_data.get('credits', {})
            crew = credits.get('crew', [])
            directors = [person.get('name', '') for person in crew if person.get('job') == 'Director']
            director = ', '.join(directors) if directors else ''
            
            return Movie(
                id=movie_id,
                title=title,
                year=year,
                rating=rating,
                director=director,
                genre=genre,
                poster_url=poster_url,
                description=description,
                source="tmdb"
            )
        except Exception as e:
            logger.error(f"Error converting TMDB data to Movie: {e}")
            # 返回一个默认的Movie对象
            return Movie(
                id=str(tmdb_data.get('id', '')),
                title=tmdb_data.get('title', '未知电影'),
                year=0,
                rating=0.0,
                director='',
                genre=[],
                poster_url='',
                description='',
                source="tmdb"
            )
    
    def _extract_year(self, release_date: str) -> int:
        """从发布日期中提取年份"""
        if not release_date:
            return 0
        try:
            return int(release_date.split('-')[0])
        except (ValueError, IndexError):
            return 0
    
    def get_genre_id_by_name(self, genre_name: str, language: str = None) -> Optional[int]:
        """根据类型名称获取类型ID"""
        genres_data = self.get_movie_genres(language)
        genres = genres_data.get('genres', [])
        
        for genre in genres:
            if genre.get('name', '').lower() == genre_name.lower():
                return genre.get('id')
        
        return None